package org.agony2d.view.puppet
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.utils.getQualifiedClassName;
	import org.agony2d.Agony;
	import org.agony2d.core.agony_internal;
	import org.agony2d.debug.Logger;
	import org.agony2d.loader.ILoader;
	import org.agony2d.loader.LoaderManager;
	import org.agony2d.notify.AEvent;
	import org.agony2d.notify.ErrorEvent;
	import org.agony2d.view.core.Component;
	import org.agony2d.view.core.ComponentProxy;
	import org.agony2d.view.puppet.supportClasses.ImagePuppetComp;
	
	use namespace agony_internal;
	
	[Event(name = "complete", type = "org.agony2d.notify.AEvent")]
	
	/** 画像傀儡
	 *  [◆◆◇]
	 * 		1. clearImageCache
	 *  [◆]
	 * 		1. isEmpty
	 * 		2. key
	 * 		3. bitmapData
	 *  [◆◆]
	 * 		1. embed
	 * 		2. load
	 */
final public class ImagePuppet extends ComponentProxy 
{
	
	public function ImagePuppet( alignCode:int = 7, pivotOffsetX:Number = 0, pivotOffsetY:Number = 0 ) 
	{
		m_view          =  ImagePuppetComp.getImagePuppetComp(this)
		m_alignCode     =  alignCode
		m_pivotOffsetX  =  pivotOffsetX
		m_pivotOffsetY  =  pivotOffsetY
	}
	
	/** ◆◆◇清理画像缓存
	 */
	public static function clearImageCache() : void
	{
		m_bitmapDataList = {}
	}
	
	/** ◆是否空画像 */
	public function get isEmpty() : Boolean { return m_key == null }
	
	/** ◆画像源名称 */
	public function get key() : String { return m_key }
	
	/** ◆画像数据(想要空白化，设为null) */
	public function get bitmapData() : BitmapData { return m_view.m_img.bitmapData }
	public function set bitmapData( v:BitmapData ) : void
	{
		this.checkAndStopLoad()
		m_key = null
		m_view.m_img.bitmapData = v
	}
	
	/** ◆◆嵌入
	 *  @param	bitmapRef
	 *  @param	cached
	 */
	public function embed( bitmapRef:Class, cached:Boolean = true ) : void
	{
		var key:String
		var BP:Bitmap
		var BA:BitmapData
		
		this.checkAndStopLoad()
		key  =  getQualifiedClassName(bitmapRef)
		BA   =  m_bitmapDataList[key]
		if (!BA)
		{
			try
			{
				BP = new bitmapRef()
			}
			catch (error:Error)
			{
				Logger.reportError(this, 'embed', '参数定义类型错误...!')
			}
			BA = BP.bitmapData
			if (cached)
			{
				m_bitmapDataList[key] =  BA
			}
		}
		m_view.m_img.bitmapData  =  BA
		m_key                    =  key
		this.adjustAlign()
	}
	
	/** ◆◆载入
	 *  @param	url
	 *  @param	cached
	 *  @param	optional
	 */
	public function load( url:String, cached:Boolean = true, optional:* = null ) : void
	{
		var BA:BitmapData
		
		this.checkAndStopLoad()
		BA = m_bitmapDataList[url]
		if (BA)
		{
			m_view.m_img.bitmapData  =  BA
			m_key                    =  url
			
			this.adjustAlign()
			return
		}
		// 预载画像
		if(optional is Class)
		{
			this.embed(optional as Class)
		}
		else if (optional is BitmapData)
		{
			this.bitmapData = optional as BitmapData
		}
		m_cached  =  cached
		m_loader  =  LoaderManager.getInstance().getLoader(url)
		m_loader.addEventListener(AEvent.COMPLETE, onComplete)
		m_loader.addEventListener(ErrorEvent.IO_ERROR, onFail)
	}
	
	agony_internal function onComplete( e:AEvent ) : void
	{
		var BA:BitmapData
		
		BA = (m_loader.data as Bitmap).bitmapData
		if (m_cached)
		{
			m_bitmapDataList[m_loader.url] = BA
		}
		m_view.m_img.bitmapData  =  m_cached ? BA.clone() : BA
		m_key                    =  m_loader.url
		m_loader                 =  null
		this.adjustAlign()
		m_view.m_notifier.dispatchDirectEvent(AEvent.COMPLETE)
	}
	
	agony_internal function onFail( e:ErrorEvent ) : void
	{
		Logger.reportWarning(this, 'onFail', 'IO: ' + m_loader.url)
		m_loader  =  null
		m_key     =  null
	}
	
	agony_internal function checkAndStopLoad() : void
	{
		if (m_loader)
		{
			m_loader.removeEventListener(Event.COMPLETE, onComplete)
			m_loader.removeEventListener(IOErrorEvent.IO_ERROR, onFail)
			m_loader = null
		}
	}
	
	agony_internal function adjustAlign() : void
	{	
		switch(m_alignCode)
		{
			case 7:
				m_view.m_img.x = m_view.m_img.y = 0
				break
			case 8:
				m_view.m_img.x = -m_view.m_img.width / 2
				m_view.m_img.y = 0
				break
			case 9:
				m_view.m_img.x = -m_view.m_img.width
				m_view.m_img.y = 0
				break
			case 4:
				m_view.m_img.x = 0
				m_view.m_img.y = -m_view.m_img.height / 2
				break
			case 5:
				m_view.m_img.x = -m_view.m_img.width / 2
				m_view.m_img.y = -m_view.m_img.height / 2
				break
			case 6:
				m_view.m_img.x = -m_view.m_img.width
				m_view.m_img.y = -m_view.m_img.height / 2
				break
			case 1:
				m_view.m_img.x = 0
				m_view.m_img.y = -m_view.m_img.height
				break
			case 2:
				m_view.m_img.x = -m_view.m_img.width / 2
				m_view.m_img.y = -m_view.m_img.height
				break
			case 3:
				m_view.m_img.x = -m_view.m_img.width
				m_view.m_img.y = -m_view.m_img.height
				break
			default:
				break
		}
		m_view.m_img.x -= m_pivotOffsetX
		m_view.m_img.y -= m_pivotOffsetY
	}
	
	override agony_internal function get view() : Component { return m_view }
	
	override agony_internal function get shell() : DisplayObject { return m_view }
	
	override agony_internal function dispose() : void
	{
		this.bitmapData = null
		super.dispose()
	}
	
	agony_internal static var m_bitmapDataList:Object = {}
	
	agony_internal var m_view:ImagePuppetComp
	agony_internal var m_loader:ILoader
	agony_internal var m_key:String
	agony_internal var m_alignCode:int
	agony_internal var m_cached:Boolean
	agony_internal var m_pivotOffsetX:Number, m_pivotOffsetY:Number
}
}